package objects;

import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

import audioPlayer.AudioPlayer;
import com.google.gson.annotations.Expose;
import communication.TrackRecord;
import cont.UIController;

import drawables.Drawable;
import drawables.DrawableManager;
import drawables.Type;
import java.io.Serializable;

public class Track extends Drawable implements Serializable {
	transient Image background;
	transient Timer t;
	int id;
        transient UIController uic=null;
	double volume=0.8;
        double balance=0;
        
	transient private static int idCounter=0;
	
	static final public int TRACK_HEIGHT=30;
	static final public int TRACK_NUM=8;
	
	ArrayList<AudioClip> audioClips;
	
	transient private boolean trackSelected;

        public boolean isTrackSelected() {
            return trackSelected;
        }

        public void setTrackSelected(boolean trackSelected) {
            this.trackSelected = trackSelected;
        }
	
        
	
	public void play(){
		t = new Timer();
		for(final AudioClip ac : audioClips){
			t.schedule(new TimerTask() {
				@Override
				public void run() {
					ac.play();
				}
			}, Math.max(0, ac.getStartTime()));
		}
	}
	
	public void stop(){
		if(t!=null)
			t.cancel();
		for(final AudioClip ac : audioClips){
			ac.stop();
		}
	}
	
	
	public Track(int x , int y , Image background, UIController uic){
		super(x , y);
		width=3000;
		height=TRACK_HEIGHT;
		this.background = background;
		
		audioClips = new ArrayList<AudioClip>();
		
		id = idCounter;
		idCounter++;
                DrawableManager.get().add(this);
                this.uic = uic;
	}
	
	public void removeAudioClip(AudioClip ac){
		audioClips.remove(ac);
	}
	
	public void addAudioClip(AudioClip ac){
		int xDiff = getX();
		int calcedX = ac.getX() - xDiff;
		int q = AudioPlayer.get().getQuantizedMesurment();
		int time;
		calcedX /= q;
		time = calcedX;	// get time interval.
		calcedX *= q;
		
		calcedX += xDiff;
		
		audioClips.add(ac);
		
		if(calcedX < getX())
			ac.setX(getX());
		else
			ac.setX(calcedX);
		ac.setY(getY()+5);
		
		ac.setCurrentTrack(this);
		ac.setStartTime(time * AudioPlayer.get().getQuantizedTime());
                if(!ac.isReady())
                    ac.loadAudio();
	}
	
	public void addAudioClip(AudioClip ac, double time){
		ac.setX(AudioPlayer.get().timeToMesurment(time));
		addAudioClip(ac);
		
	}
	
	@Override
	public void paint(Graphics g) {
		g.drawImage(background,x,y, null);
		g.drawRect(x , y , width, height);
		
	}
	
	
	
	@Override
	public void onDropReceived(Drawable d){
            try {
                addAudioClip((AudioClip) d);
                ((AudioClip) d).setVolume(volume);
                ((AudioClip) d).setPan(balance);
            } catch (Exception e) {
            }
		
	}
	
	public int getId() {
		return id;
	}

	@Override
	public void paint(GraphicsContext g) {
            g.setFill(Color.AQUA);
            //g.drawImage(background,x,y, null);
            //g.fillRect(x , y , width, height);
            if(isTrackSelected()){
                //g.setStroke(Color.web("#000E96"));
                g.setLineWidth(2);

                g.setFill(Color.web("#DFDFDF"));
                g.fillRect(x , y , width, height);
            }
            else{
                //g.setStroke(Color.web("#080066"));
                g.setLineWidth(0.7);
            }
            g.setFill(Color.BLACK);
            g.strokeRect(x , y , width, height);
            g.setLineWidth(0.7);
	}
	
        @Override
	public void onLeftClick(int x , int y){
            if(UIController.getCurrentTrack()!=null) {
                UIController.getCurrentTrack().setTrackSelected(false);
            }
            UIController.setCurrentTrack(this);
            setTrackSelected(true);
            
            uic.setTrackVolumeSelector(volume);
            uic.setTrackPanSelector(balance);
        }
        
//	public AudioClip getAudioClip(long time){
//		return audioClips.get(time);
//	}

    @Override
    public Type getType() {
        return Type.TRACK;
    }
	
    public void setVolume(double volume){
        this.volume = volume;
        
        for(AudioClip ac : audioClips){
            ac.setVolume(volume);
        }
    }
    
    public double getVolume(){
        return this.volume;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
        for(AudioClip ac : audioClips){
            ac.setPan(balance);
        }
    }

    public ArrayList<AudioClip> getAudioClips() {
        return audioClips;
    }
	
    public TrackRecord getTrackRecord(){
        TrackRecord tr = new TrackRecord();
        
        for(AudioClip ac : audioClips)
            tr.clips.add(ac.getClipRecord());
        tr.balance = balance;
        tr.volume = volume;
        return tr;
    }
    
}
